﻿namespace SenenFernandez.Sensktop
{
    using SenenFernandez.Sensktop.Configuration;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;

    /// <summary>
    /// Sensktop Menu.
    /// </summary>
    public class Menu : IXmlSerializable
    {
        /// <summary>
        /// Application list.
        /// </summary>
        public List<Application> Applications { get; private set; }

        /// <summary>
        /// Plugin list.
        /// </summary>
        public List<IPlugin> Plugins { get; private set; }

        /// <summary>
        /// Initializes a new instance of the Menu class.
        /// </summary>
        public Menu()
        {
        }

        /// <summary>
        /// This method is reserved and should not be used. 
        /// </summary>
        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        public void ReadXml(XmlReader reader)
        {
            Applications = new List<Application>();
            Plugins = new List<IPlugin>();
            while (reader.Read())
            {
                if (reader.IsStartElement())
                {
                    switch (reader.Name)
                    {
                        case DefaultValue.Application:
                        {
                            var serializer = new XmlSerializer(typeof (Application));
                            var application = serializer.Deserialize(reader) as Application;
                            if (application != null)
                            {
                                Applications.Add(application);
                            }
                            break;
                        }
                        case DefaultValue.Plugins:
                        {
                            AddPlugin(reader, Plugins);
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        public void WriteXml(XmlWriter writer)
        {
        }

        private void AddPlugin(XmlReader reader, ICollection<IPlugin> list)
        {
            var subReader = reader.ReadSubtree();
            while (subReader.Read())
            {
                if (reader.Name.StartsWith(DefaultValue.PluginName))
                {
                    var fileName = reader.GetAttribute(DefaultValue.PluginAssembly);
                    if (fileName != null && System.IO.File.Exists(fileName))
                    {
                        var assembly = System.Reflection.Assembly.LoadFrom(fileName);
                        if (assembly != null)
                        {
                            var type = assembly.GetType(reader.Name);
                            if (type != null)
                            {
                                var serializer = new XmlSerializer(type, new XmlRootAttribute(reader.Name));
                                var plugin = serializer.Deserialize(reader) as IPlugin;
                                if (plugin != null)
                                {
                                    list.Add(plugin);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}